package minit

import (
	"errors"
	"gitee.com/dennis-mxx/gcode-common/mcore"
	"gitee.com/dennis-mxx/gcode-common/menv"
	"gitee.com/dennis-mxx/gcode-common/mlogger"
	"os"
	"reflect"
)

func InitializeFile(defEnv string) *mlogger.TraceLogger {
	return Initialize(&menv.FileRender{}, defEnv)
}

func Initialize(loader menv.ConfigRender, defEnv string, dest ...any) *mlogger.TraceLogger {
	var config string
	if loader.GetPath() != "" {
		config = loader.GetPath()
	} else {
		config = "./conf/config-$env.toml"
	}
	menv.SetSys("logger.level", "info")
	menv.SetSys("logger.dir", "./logger/")
	menv.SetSys("env", defEnv)
	menv.SetSys("config", config)
	menv.AppendArgs("env", defEnv, "Program running environment")
	menv.AppendArgs("config", config, "Program config path")
	fields := mcore.LoadStructTag("", "toml", reflect.TypeOf(menv.Environment).Elem())
	for i := range fields {
		menv.AppendArgs(fields[i], "", "System Program : "+fields[i])
	}

	menv.ParseArgs()

	loader.SetEnv(menv.Get("env").(string))
	loader.SetConfigPath(menv.Get("config").(string))

	readerFile := loader.Render()

	if err := menv.Unmarshal(menv.Environment); err != nil {
		panic(errors.Join(err, errors.New("load config exception")))
	}
	for i := range dest {
		if err := menv.Unmarshal(dest[i]); err != nil {
			panic(errors.Join(err, errors.New("load dest exception")))
		}
	}
	mlogger.InitZap(menv.Environment.ServerName, menv.Environment.Logger)
	logger := mlogger.DefaultTraceLogger()
	logger.Append(mlogger.TRACE_ID, "main")
	logger.Info("env [", menv.Get("env"), "]")
	logger.Info("render config file [" + readerFile + "] successful !")

	return logger
}

func Complete(logger *mlogger.TraceLogger, funds ...func(logger *mlogger.TraceLogger)) {
	for i := range funds {
		funds[i](logger)
	}
	logger.Info("<<< Environment load complete . ServerName : [", menv.Environment.ServerName, "] PID : ", os.Getpid(), " >>>")
	logger.Info("<<< mxx-core: https://gitee.com/dennis-mxx/gcode-starter/tags >>>")
}
